# coding=utf-8
import time
import hmac
import hashlib
import base64
import urllib.parse

import requests

import sina

zh_cn_space = '\u3000'
null = '\u2000'


def build_sign(secret: str):
    timestamp = str(round(time.time() * 1000))

    secret_enc = secret.encode('utf-8')
    string_to_sign = '{}\n{}'.format(timestamp, secret)
    string_to_sign_enc = string_to_sign.encode('utf-8')
    hmac_code = hmac.new(secret_enc, string_to_sign_enc, digestmod=hashlib.sha256).digest()
    sign = urllib.parse.quote_plus(base64.b64encode(hmac_code))
    return timestamp, sign


def real_price_body(measure_list: list[sina.StockMeasure], msg_type="text", title="你有新的消息送达"):
    if msg_type not in ("text", "markdown"):
        raise ValueError(f"不支持的消息类型: {msg_type}")

    body = {"msgtype": msg_type}

    if msg_type == "text":
        template = ""
        for i in measure_list:
            # template = template + f"{i.name.ljust(4, zh_cn_space)} {str(i.real_price).rjust(10, null)}  {str(i.rise).rjust(10, null)}\n"
            template = template + f"{i.name[0]} {i.rise} {i.real_price}\n"
        body["text"] = {"content": template}
    else:
        template = """\
|Stock Name |  Current Price | Current Rise   |
|:---       |     ---:       |      ---:      |
"""
        for i in measure_list:
            template = template + f"| {i.name} | {i.real_price} | {i.rise} |\n"

        body["markdown"] = {
            "title": title,
            "text": template
        }

    return body


def price_warn_body(measure: sina.StockMeasure):
    body = {
        "msgtype": "text",
        "at": {
            "isAtAll": True,
        },
        "text": {
            "content": f"{measure.name} {measure.rise} !"
        }
    }

    return body


def send(body: dict, access_token, secret):
    webhook_base_url = "https://oapi.dingtalk.com/robot/send"
    webhook_url = "{}?access_token={}&timestamp={}&sign={}".format(webhook_base_url, access_token, *build_sign(secret))
    resp = requests.post(webhook_url, json=body, headers={"Content-Type": "application/json; charset=utf-8"})
    if resp.status_code > 299 or resp.status_code < 200:
        raise RuntimeError(f"{resp.text}")

    if str(resp.json().get("errcode")) != "0":
        raise RuntimeError(f"{resp.json().get('errmsg')}")


if __name__ == '__main__':
    import settings
    codes = [
        "sz002371",
        "sz002156",
        "sz002687",
    ]
    data = sina.get_stock_data(codes)
    # send(real_price_body(data, msg_type="text"), settings.ACCESS_TOKEN, settings.SECRET)
    send(price_warn_body(data[0]), settings.ACCESS_TOKEN, settings.SECRET)
